package com.ruoyi.app.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ruoyi.bizsys.domain.AppUser;
import com.ruoyi.bizsys.domain.AppUserMark;
import com.ruoyi.bizsys.domain.ExtTryQueue;
import com.ruoyi.bizsys.service.IAppUserService;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author cyh
 * @date 2022/6/29 5:24 下午
 */
@Slf4j
@Service
public class ResetUserInviteCode {

    @Autowired
    private IAppUserService appUserService;

    @Autowired
    private InviteCodePool inviteCodePool;

    public void initialization() {

        List<Long> digitInviteCodeUser = appUserService.get8DigitInviteCodeUser();
        if (digitInviteCodeUser.size() == 0) {
            return;
        }
        log.info("digitInviteCodeUser Size:{}", digitInviteCodeUser.size());
        int size = (digitInviteCodeUser.size() / 500) + 1;
        List<List<Long>> lists = ObjectUtil.averageAssign(digitInviteCodeUser, size);

        int coreSize = 4;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(coreSize, coreSize, 0L, TimeUnit.MILLISECONDS, workQueue);

        CountDownLatch latch = new CountDownLatch(lists.size());
        lists.forEach(userList -> {
            threadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        log.info("RUN Begin" + Thread.currentThread().getName());
                        resetInviteCodeList(userList);
                        log.info("RUN End" + Thread.currentThread().getName());
                    } finally {
                        latch.countDown();
                    }
                }
            });
        });
        try {
            latch.await();
        } catch (InterruptedException e) {
            log.info("threadPoolExecutorError");
            throw new BusinessException(e.getMessage());
        } finally {
            threadPoolExecutor.shutdown();
        }

    }

    private void resetInviteCodeList(List<Long> userIds) {
        log.info("resetInviteCodeList Size:{}", userIds.size());
        List<AppUser> objects = new ArrayList<>();
        userIds.forEach(userId -> {
            AppUser appUser = new AppUser();
            appUser.setUserId(userId);
            appUser.setInviteCode(inviteCodePool.assignInviteCode(false));
            objects.add(appUser);
        });
        appUserService.updateBatchById(objects);
    }

}
